﻿using CaseManagerLibrary.Http;
using CaseManagerLibrary.Models;
using Newtonsoft.Json;
using PSDClientService.SystemSettings;
using PSDLib.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSDClientService.Download
{
    public class CaseLogDownloadManager
    {
        private DownloadContext context;
        DateTime lastCheckpoint;
        int downloadHour = 0;
        int downloadMin = 1;
        bool downloading = false;
        private object lock_downloading = new object();

        int RestartInterval = 1440;
        private System.Threading.Thread logThread = null;

        private List<dl_task> taskList;
        public List<dl_case_log> CaseLogList { get; set; }

        public CaseLogDownloadManager(DownloadContext ctx)
        {
            taskList = new List<dl_task>();
            CaseLogList = new List<dl_case_log>();

            context = ctx;
        }

        public bool Init()
        {
            bool ret = false;

            //间隔时间 60分钟x24小时
            RestartInterval = 60 * 24;

            string[] temp = AppSettings.Setting.CaseLogDownloadTime.Split(":".ToCharArray());

            if (temp.Length > 1)
            {
                if (int.TryParse(temp[0], out downloadHour) && int.TryParse(temp[1], out downloadMin))
                {
                    ret = true;
                }
            }

            return ret;
        }

        public void StartDownload()
        {
            logThread = new System.Threading.Thread(new System.Threading.ThreadStart(DoWork));
            logThread.Start();
        }

        public void StopDownload()
        {
            try
            {
                logThread.Abort();
            }
            catch { }
        }

        private void DoWork()
        {
            while (context.Running && !context.Closing)
            {
                if (CheckTime())
                {
                    DownloadAll();
                }

                System.Threading.Thread.Sleep(1000 * 60);
            }
        }

        private void DownloadAll()
        {
            lock (lock_downloading)
            {
                if (downloading)
                    return;

                downloading = true;
            }

            GetUnhandleLogList();

            foreach (var log in CaseLogList)
            {
                DownloadLog(log);

                System.Threading.Thread.Sleep(2000);
            }

            if (taskList.Count > 0)
            {
                foreach (var task in taskList)
                {
                    CleanUpTempData(task.object_id);
                }

                context.Logger.Log($"已清理办案日志下载服务器临时文件");
            }


            foreach (var task in taskList)
            {
                if (task.task_type == (int)DownloadTaskCreateType.常规Routine)
                {
                    var paramData = new Dictionary<string, string>();
                    paramData.Add("taskId", task.id);
                    var ret = HttpHelper.Post<HResult>(AppSettings.Setting.API.TryFinishDownloadTask, paramData);
                }
            }

            taskList.Clear();
            CaseLogList.Clear();


            downloading = false;
        }

        private bool CheckTime()
        {
            bool ret = false;
            DateTime now = DateTime.Now;

            if (now.Hour == downloadHour && now.Minute == downloadMin)
            {
                ret = true;
            }

            return ret;
        }

        /// <summary>
        /// 获取未下载完成的办案日志
        /// </summary>
        private void GetUnhandleLogList()
        {
            var result_task = HttpHelper.Get<HResult<List<dl_task>>>(AppSettings.Setting.API.GetDeviceTaskList + "?deviceId=" + context.Device.id);

            if (result_task.success)
            {
                taskList.AddRange(result_task.data);

                string[] types = Enum.GetNames(typeof(DownloadLogType));

                foreach (var task in taskList)
                {
                    if (task.task_type == (int)DownloadTaskCreateType.常规Routine)
                    {
                        foreach (string type in types)
                        {
                            if (type != DownloadLogType.All.ToString())
                            {
                                var result_log = HttpHelper.Get<HResult<List<dl_case_log>>>(AppSettings.Setting.API.GetUnhandleLogList + "?logType=" + type + "&objectId=" + task.object_id);

                                if (result_log.success)
                                {
                                    CaseLogList.AddRange(result_log.data);

                                    context.Logger.Log($"获取待下载的办案日志：{type} {result_log.data.Count}件");
                                }
                            }
                        }
                    }
                }

                context.Logger.Log($"获取待下载的办案日志：共{CaseLogList.Count}件");
            }
        }

        private void DownloadLog(dl_case_log log)
        {
            try
            {
                var data = new Dictionary<string, string>();
                data.Add("LogId", log.id);
                var result_start = HttpHelper.Post<HResult>(AppSettings.Setting.API.StartDownloadLog, data);

                if (!result_start.success)
                {
                    context.Logger.Error($"设置办案日志下载状态失败：{log.file_name}");
                    return;
                }

                context.Logger.Log($"开始下载办案日志：{log.file_name}");

                var main_st = context.Device.StorageList.Where(t => t.storage_type == 0 && t.state == 1).FirstOrDefault();

                if (main_st == null)
                    return;

                string logPath = System.IO.Path.Combine(
                    main_st.storage_driver + "\\",
                    "办案日志",
                    $"{log.object_room}_{ log.object_name}",
                    GetLogFolder((DownloadLogType)Enum.Parse(typeof(DownloadLogType), log.log_type)));

                if (!System.IO.Directory.Exists(logPath))
                {
                    System.IO.Directory.CreateDirectory(logPath);
                }

                string filePath = System.IO.Path.Combine(logPath, log.file_name);

                DateTime st = DateTime.Now;

                string url = AppSettings.Setting.ApiServerAddress + $"api/casehandling/LogQuery?objectId={log.object_id}&date={log.log_time.ToString("yyyy-MM-dd")}&logType={log.log_type}";

                var result_file = HttpHelper.HttpDownload(url, filePath);

                DateTime et = DateTime.Now;

                log.dl_start_time = st;
                log.dl_end_time = et;

                if (result_file.success)
                {
                    context.Logger.Log($"办案日志下载到主存成功：{filePath}");

                    var fi = new System.IO.FileInfo(filePath);
                    log.file_path = filePath;
                    log.file_size = fi.Length;
                    log.dl_speed = Convert.ToInt64(fi.Length / (et - st).TotalSeconds);
                    log.error_log = "";

                    if (context.ClientContext.Device.storage_type == 0)
                    {
                        if (CopyToBackupStorage(log))
                        {
                            log.state = 1;
                        }
                        else
                        {
                            log.state = 2;
                            log.error_log = "复制案件日志到备存失败";
                        }
                    }
                    else
                    {
                        log.state = 1;
                    }
                }
                else
                {
                    log.state = 2;
                    log.error_log = result_file.message;
                    context.Logger.Error($"办案日志下载失败：{filePath}, {log.error_log}");
                }

                context.Logger.Log($"Start DownloadLogComplete ：{JsonConvert.SerializeObject(log)}");
                var result_complete = HttpHelper.Post<HResult>(AppSettings.Setting.API.DownloadLogComplete, JsonConvert.SerializeObject(log));
                context.Logger.Log($"DownloadLogComplete ：{result_complete.success}");
            }
            catch (Exception ex)
            {
                string err = ex.Message + (ex.InnerException == null ? "" : ex.InnerException.Message);
                context.Logger.Error($"DownloadLog Error: {err}");
            }
        }

        private bool CopyToBackupStorage(dl_case_log file)
        {
            bool success = false;

            string srcFile = "";
            string destPath = "";
            string destFile = "";
            try
            {
                var currMainStorage = context.Device.StorageList.Where(t => t.storage_type == 0 && t.state == 1).FirstOrDefault();

                if (currMainStorage != null)
                {
                    var currBackupStorage = context.Device.StorageList.Where(t => t.storage_type == 1 && t.storage_group == currMainStorage.storage_group).FirstOrDefault();

                    if (currBackupStorage != null)
                    {
                        //srcFile = System.IO.Path.Combine(file.file_path, file.file_name);
                        srcFile = file.file_path;
                        destPath = file.file_path.Replace(currMainStorage.storage_driver, currBackupStorage.storage_driver);
                        destFile = System.IO.Path.Combine(destPath, file.file_name);

                        if (!System.IO.Directory.Exists(destPath))
                        {
                            System.IO.Directory.CreateDirectory(destPath);
                        }

                        System.IO.File.Copy(srcFile, destFile, true);

                        context.Logger.Log("复制案件日志到备存成功：" + destFile);

                        success = true;
                    }
                    else
                    {
                        context.Logger.Error("复制案件日志到备存出错：未找到可用的备存信息。" + "srcFile=" + System.IO.Path.Combine(file.file_path, file.file_name));
                    }
                }
                else
                {
                    context.Logger.Error("复制案件日志到备存出错：未找到可用的主存信息。" + "srcFile=" + System.IO.Path.Combine(file.file_path, file.file_name));
                }
            }
            catch (Exception ex)
            {
                context.Logger.Error("复制案件日志到备存出错：" + ex.Message + (ex.InnerException == null ? "" : ex.InnerException.Message) + "。 src=" + srcFile + " dest=" + destFile);
            }

            return success;
        }

        private string GetLogFolder(DownloadLogType type)
        {
            switch (type)
            {
                case DownloadLogType.MonitoringLog:
                    return "监控日志";
                case DownloadLogType.HealthLog:
                    return "健康日志";
                case DownloadLogType.CMFeedbackLog:
                    return "案管每日反馈日志";
                case DownloadLogType.InvestigateLog:
                    return "审查调查工作日志";
                case DownloadLogType.SecurityLog:
                    return "安全员工作日志";
                case DownloadLogType.SuperviceLog:
                    return "专班监督日志";
                default:
                    return "";
            }
        }

        private void CleanUpTempData(string objectId)
        {
            string url = AppSettings.Setting.ApiServerAddress + $"api/casehandling/DeleteLogs?objectId={objectId}";

            var result = HttpHelper.Get<HResult>(url);
        }

        public void DownloadImmediate()
        {
            DownloadAll();


        }

        public void Dispose()
        { }
    }


}
